﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Dataglot.Utils
{

    /// <summary>
    /// Sets Id to Thread Id, checks for ShouldTrace and puts the Type in the Method name.
    /// </summary>
    /// <remarks>
    /// If you invoke with the syntax of TraceApp.Info(()=>SomeExpensiveString())
    /// The method SomeExpensiveString will only be called if ShouldTrace is true.
    /// </remarks>
    public static class TraceApp
    {
        private static readonly TraceSource trace= new TraceSource("Dataglot.App");

        [DebuggerStepThrough]
        public static void Info(Func<string> messageMaker)
        {
            if(trace.Switch.ShouldTrace(TraceEventType.Information))
            {
                trace.TraceInformation(messageMaker.Invoke());
            }
        }

        [DebuggerStepThrough]
        public static void Info(string message)
        {
            if(trace.Switch.ShouldTrace(TraceEventType.Information))
            {
                trace.TraceInformation(message);
            }
        }
        [DebuggerStepThrough]
        public static void Info(string message, params object[] args)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Information))
            {
                trace.TraceInformation(message, args);
            }
        }

        [DebuggerStepThrough]
        public static void Warn(Func<string> messageMaker)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Warning))
            {
                TraceTypeWithId(TraceEventType.Warning, messageMaker.Invoke());
            }
        }

        [DebuggerStepThrough]
        public static void Warn(string message)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Warning))
            {
                TraceTypeWithId(TraceEventType.Warning, message);
            }
        }
        [DebuggerStepThrough]
        public static void Warn(string message, params object[] args)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Warning))
            {
                TraceTypeWithIdAndArgs(TraceEventType.Warning, message, args);
            }
        }
        [DebuggerStepThrough]
        public static void Error(Func<string> messageMaker)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Error))
            {
                TraceTypeWithId(TraceEventType.Error, messageMaker.Invoke());
            }
        }
        [DebuggerStepThrough]
        public static void Error(string message)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Error))
            {
                TraceTypeWithId(TraceEventType.Error, message);
            }
        }
        [DebuggerStepThrough]
        public static void Error(string message, params object[] args)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Error))
            {
                TraceTypeWithIdAndArgs(TraceEventType.Error, message, args);
            }
        }
        [DebuggerStepThrough]
        public static void Verbose(string message)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Verbose))
            {
                TraceTypeWithId(TraceEventType.Verbose, message);
            }
        }
        [DebuggerStepThrough]
        public static void Verbose(Func<string> messageMaker)
        {
            if (trace.Switch.ShouldTrace(TraceEventType.Verbose))
            {
                TraceTypeWithId(TraceEventType.Verbose, messageMaker.Invoke());
            }
        }
        [DebuggerStepThrough]
        public static void Verbose(string message, params object[] args)
        {
            TraceTypeWithIdAndArgs(TraceEventType.Verbose, message, args);
        }
        [DebuggerStepThrough]
        private static void TraceTypeWithId(TraceEventType type, string message)
        {
            int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
            trace.TraceEvent(type, id, message);
        }
        [DebuggerStepThrough]
        private static void TraceTypeWithIdAndArgs(TraceEventType type, string message, params object[] args)
        {
            int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
            trace.TraceEvent(type, id, message, args);
        }
    }
}
